package com.aoxiang.zbox.service.impl;

import com.aoxiang.zbox.mapper.TodoSortMapper;
import com.aoxiang.zbox.model.dto.UpdateSortDTO;
import com.aoxiang.zbox.model.entity.TodoSort;
import com.aoxiang.zbox.model.enums.TodoSortTypeEnum;
import com.aoxiang.zbox.service.TodoSortService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Description:
 *
 * @author: aoxiang
 * @create: 2025-03-08 20:41
 **/

@Service
public class TodoSortServiceImpl extends ServiceImpl<TodoSortMapper, TodoSort> implements TodoSortService {
    @Autowired
    private TodoSortMapper todoSortMapper;

    @Override
    public void updateCompletedSort(UpdateSortDTO updateSortDto) {
        List<Long> todoItemIds = updateSortDto.getTodoItemIds();
        LambdaUpdateWrapper<TodoSort> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(TodoSort::getShowSort, null)
                .eq(TodoSort::getLabelId, updateSortDto.getLabelId())
                .eq(TodoSort::getSortType, TodoSortTypeEnum.COMPLETED_SORT.getType());
        for (int i = 0; i < todoItemIds.size(); i++) {
            LambdaUpdateWrapper<TodoSort> updateWrapper1 = new LambdaUpdateWrapper<>();
            updateWrapper1.set(TodoSort::getShowSort, i + 1)
                    .eq(TodoSort::getTodoId, todoItemIds.get(i))
                    .eq(TodoSort::getLabelId, updateSortDto.getLabelId())
                    .eq(TodoSort::getSortType, TodoSortTypeEnum.COMPLETED_SORT.getType());
            todoSortMapper.update(null, updateWrapper1);
        }
    }

    @Override
    public void updateShowSort(UpdateSortDTO updateSortDto) {
        List<Long> todoItemIds = updateSortDto.getTodoItemIds();
        LambdaUpdateWrapper<TodoSort> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(TodoSort::getShowSort, null)
                .eq(TodoSort::getLabelId, updateSortDto.getLabelId())
                .eq(TodoSort::getSortType, TodoSortTypeEnum.SHOW_SORT.getType());
        for (int i = 0; i < todoItemIds.size(); i++) {
            LambdaUpdateWrapper<TodoSort> updateWrapper1 = new LambdaUpdateWrapper<>();
            updateWrapper1.set(TodoSort::getShowSort, i + 1)
                    .eq(TodoSort::getTodoId, todoItemIds.get(i))
                    .eq(TodoSort::getLabelId, updateSortDto.getLabelId())
                    .eq(TodoSort::getSortType, TodoSortTypeEnum.SHOW_SORT.getType());
            todoSortMapper.update(null, updateWrapper1);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNewTodoItemSort(Long todoItemId, Long labelId, Integer sortType) {
        Integer maxSort = getMaxSort(labelId);
        if (maxSort == null) {
            maxSort = 0;
        }
        TodoSort todoSort = new TodoSort();
        todoSort.setTodoId(todoItemId);
        todoSort.setLabelId(labelId);
        todoSort.setShowSort(maxSort + 1);
        todoSort.setSortType(sortType);
        todoSortMapper.insert(todoSort);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByTodoItemIdAndLabelId(Long todoId, Long labelId, Integer sortType) {
        LambdaQueryWrapper<TodoSort> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TodoSort::getTodoId, todoId)
                .eq(TodoSort::getLabelId, labelId)
                .eq(TodoSort::getSortType, sortType);
        TodoSort todoSort = todoSortMapper.selectOne(queryWrapper);
        if (todoSort != null) {
            todoSortMapper.deleteById(todoSort.getId());
            updateShowSort(labelId, todoSort.getShowSort(), sortType);
        }
    }

    @Override
    public void removeByTodoItemId(Long todoId) {
        LambdaQueryWrapper<TodoSort> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TodoSort::getTodoId, todoId);
        List<TodoSort> todoSorts = todoSortMapper.selectList(queryWrapper);
        todoSortMapper.delete(queryWrapper);
        for (TodoSort todoSort : todoSorts) {
            updateShowSort(todoSort.getLabelId(), todoSort.getShowSort(), todoSort.getSortType());
        }
    }

    /**
     * 更新标签下排序大于 showSort的全部加一
     *
     * @param labelId
     * @param showSort
     * @return void
     * @author aoxiang
     * @create 2025/3/9
     **/
    private void updateShowSort(Long labelId, Integer showSort, Integer sortType) {
        LambdaUpdateWrapper<TodoSort> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(TodoSort::getShowSort, null) // 避免默认值干扰
                .setSql("show_sort = show_sort - 1")
                .eq(TodoSort::getLabelId, labelId)
                .gt(TodoSort::getShowSort, showSort)
                .eq(TodoSort::getSortType, sortType);
        todoSortMapper.update(null, updateWrapper);
    }

    @Override
    public Integer getMaxSort(Long labelId) {
        return todoSortMapper.selectMaxSort(labelId);
    }
}
